<?php

namespace app\api\service;

use app\model\Agent;
use app\model\AgentBalanceLog as ModelAgentBalanceLog;
use app\model\BaseSupplier;
use think\facade\Db;

/**
 * 供应商相关.
 */
class SupplierService extends CommonService
{
    public $orderModel;

    /*
    供应商回调通知后流程处理 == DB事务版本
    data 回调数据 ['sn' => '平台订单号','supplier_order_sn'=>'供应商订单号'] 如有增加请通知查看各调用地方
    status 供应商转 平台订单的取值
    */
    public function notifyTrans($data, $status)
    {
        Db::startTrans();
        try {
            $res = $this->notify($data, $status);
            if ($res['code']) {
                Db::rollback();

                return $res;
            }
            Db::commit();

            return $res;
        } catch (\Exception $e) {
            Db::rollback();
            doWarning(getExceptionMsg($e));

            return $this->inValiReturn('处理供应商回调失败');
        }
    }

    /*
     供应商回调通知后流程处理
     data 回调数据 ['sn' => '平台订单号','supplier_order_sn'=>'供应商订单号'] 如有增加请通知查看各调用地方
     status 供应商转 平台订单的取值
    */
    public function notify($data, $status)
    {
        $orderInfo = ($this->orderModel)::where('sn', $data['sn'])->find();
        if (!$orderInfo || !$orderInfo->pay_status) {
            doWarning('供应商充值回调，订单不存在或者未支付'.json_encode($orderInfo));

            return $this->inValiReturn('订单不存在或者未支付');
        }

        // 防止多次通知
        if ($orderInfo->status == $status) {
            return $this->inValiReturn('已经通知过了');
        }

        if (!empty($data['supplier_order_sn'])) {
            $orderInfo->supplier_sn = $data['supplier_order_sn'];
        }
        // 供应商状态映射order表 status 状态
        $update['status'] = $status;

        // 充值成功后处理
        if (3 === $status) {
            $update['complete_at'] = date('Y-m-d H:i:s');

            // step  代理商佣金处理
            if (SETTLE_TYPE_PROFIT == $orderInfo->agent_settle_type) {
                $update['agent_settle_status'] = 3;
                $oldBalance = Agent::find($orderInfo->agent_id)->value('profit_balance');
                $res = Agent::where('id', $orderInfo->agent_id)
                    ->inc('profit_balance', $orderInfo->agent_profit)
                    ->inc('total_profit', $orderInfo->agent_profit)
                    ->update([
                        'balance_last_updated_at' => date('Y-m-d H:i:s'),
                    ]);
                if (!$res) {
                    return $this->inValiReturn('更新代理商返佣失败');
                }

                $agentBalanceModel = new ModelAgentBalanceLog();
                $remark = PRODUCT_SERV_TYPE[$orderInfo->serv_type]['name'].'业务，面额：'.
                        fen2yuan($orderInfo->origin_amount).'元，售价:'.
                        fen2yuan($orderInfo->amount).'元，结算：'.
                        fen2yuan($orderInfo->amount - $orderInfo->agent_profit).'元,利润：'.
                        fen2yuan($orderInfo->agent_profit).'元。订单号：'.$orderInfo->sn;
                $balanceData = [
                    'agent_id' => $orderInfo->agent_id,
                    'type' => $orderInfo->agent_id,
                    'amount' => $orderInfo->agent_profit,
                    'old_balance' => $oldBalance,
                    'new_balance' => ($oldBalance + $orderInfo->agent_profit),
                    'remark' => $remark,
                    'quote_id' => $orderInfo->id,
                    'trade_no' => $orderInfo->sn,
                ];

                $res = $agentBalanceModel->save($balanceData);
                if (!$res) {
                    return $this->inValiReturn('入口财务明细失败，重试或者联系我们');
                }
            }

            // step 供应商 余额相关处理
            if (SETTLE_TYPE_PROFIT == $orderInfo->supplier_settle_type) {
                $res = BaseSupplier::where('id', $orderInfo->supplier_id)->dec('balance', ($orderInfo->supplier_settle_value * $orderInfo->origin_amount / 100))->update();
                if (!$res) {
                    return $this->inValiReturn('入口财务明细失败，重试或者联系我们');
                }
            }
        }

        // todo 失败状态的话，切换供应商 如果没有供应商则设置待退款

        // 更新订单
        // todo 待处理 ，短时间多次不同状态的通知 或者 延迟通知时候，前面流程覆盖后续（比如：status=2 通知中 覆盖 通知成功status=3 ）
        $res = ($this->orderModel)::where('id', $orderInfo->id)->where('status', $orderInfo->status)->update($update);
        if (!$res) {
            return $this->inValiReturn('回调订单更新失败');
        }

        return $this->valiReturn();
    }

    /*
     设置订单对应的模型
    */
    public function setOrderModel($orderModel)
    {
        $this->orderModel = $orderModel;

        return $this;
    }
}
